/**
 * @file device_listener.c
 * @brief 设备监听器实现
 */

#define _POSIX_C_SOURCE 200809L

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <pthread.h>
#include <unistd.h>
#include <time.h>
#include "../include/device_listener.h"
#include "../../../common/logs/include/logger.h"
#include "../../../../protocol/104/core/api/include/protocol_interface.h"

#define LOG_MODULE_NAME "DEVICE_LISTENER"

/* ==================== 内部数据结构 ==================== */

/**
 * @brief 设备监听器内部数据
 */
typedef struct {
    int protocol_type;                  /* 协议类型 */
    char product_key[64];               /* 产品Key */
    char device_name[128];              /* 设备名称 */
    void* iot_platform_handle;          /* IoT平台句柄 */
    
    /* 协议相关 */
    protocol_handle_t protocol_104_handle;  /* 104协议句柄 */
    void* protocol_3761_handle;            /* 3761协议句柄（待实现） */
    void* protocol_3762_handle;            /* 3762协议句柄（待实现） */
    
    /* 线程控制 */
    pthread_t listen_thread;            /* 监听线程 */
    bool running;                       /* 运行标志 */
    pthread_mutex_t mutex;              /* 互斥锁 */
} device_listener_private_t;

/* ==================== 辅助函数 ==================== */

/**
 * @brief 从产品名中提取协议类型（公开函数，头文件中已声明）
 */
int extract_protocol_type_from_product_name(const char* product_name) {
    if (product_name == NULL || strlen(product_name) == 0) {
        LOG_ERROR(LOG_MODULE_NAME, "产品名为空");
        return -1;
    }
    
    // 查找下划线位置
    const char* underscore = strchr(product_name, '_');
    if (underscore == NULL) {
        // 没有下划线，尝试直接解析数字
        int protocol_type = atoi(product_name);
        if (protocol_type > 0) {
            LOG_DEBUG(LOG_MODULE_NAME, "从产品名中提取协议类型: %s -> %d", product_name, protocol_type);
            return protocol_type;
        }
        LOG_WARN(LOG_MODULE_NAME, "无法从产品名中提取协议类型: %s", product_name);
        return -1;
    }
    
    // 提取下划线前的数字
    size_t prefix_len = underscore - product_name;
    if (prefix_len == 0 || prefix_len > 10) {
        LOG_WARN(LOG_MODULE_NAME, "产品名前缀长度无效: %s", product_name);
        return -1;
    }
    
    char prefix[16];
    strncpy(prefix, product_name, prefix_len);
    prefix[prefix_len] = '\0';
    
    int protocol_type = atoi(prefix);
    if (protocol_type <= 0) {
        LOG_WARN(LOG_MODULE_NAME, "无法解析协议类型: %s (前缀: %s)", product_name, prefix);
        return -1;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "从产品名中提取协议类型: %s -> %d", product_name, protocol_type);
    return protocol_type;
}

/**
 * @brief 组装设备数据为IoT平台格式
 */
static char* assemble_iot_data(const char* device_name, const char* data_type, 
                              const char* data_json, int64_t timestamp) {
    if (device_name == NULL || data_type == NULL || data_json == NULL) {
        return NULL;
    }
    
    // 组装为IoT平台的属性上报格式
    // 格式: {"properties": {"property_name": value}}
    // 这里简化处理，将原始数据作为属性值
    
    size_t buffer_size = 512 + strlen(device_name) + strlen(data_type) + strlen(data_json);
    char* buffer = (char*)malloc(buffer_size);
    if (buffer == NULL) {
        return NULL;
    }
    
    snprintf(buffer, buffer_size,
             "{\"device_name\":\"%s\",\"timestamp\":%ld,\"%s\":%s}",
             device_name, timestamp, data_type, data_json);
    
    return buffer;
}

/**
 * @brief 上报数据到IoT平台
 */
static int report_to_iot_platform(device_listener_private_t* listener, const char* data_json) {
    if (listener == NULL || data_json == NULL || listener->iot_platform_handle == NULL) {
        return -1;
    }
    
    // TODO: 调用IoT平台的上报接口
    // 这里需要使用iotplatform模块的接口
    // 例如: iot_property_post(listener->iot_platform_handle, timestamp, data_json);
    
    LOG_DEBUG(LOG_MODULE_NAME, "上报数据到IoT平台: %s", data_json);
    
    return 0;
}

/**
 * @brief 104协议数据接收回调
 */
static void protocol_104_data_callback(const void* data, void* user_data) {
    if (data == NULL || user_data == NULL) {
        return;
    }
    
    device_listener_private_t* listener = (device_listener_private_t*)user_data;
    const data_point_t* data_point = (const data_point_t*)data;
    
    LOG_DEBUG(LOG_MODULE_NAME, "收到104协议数据: 地址=%u, 类型=%d", 
              data_point->address, data_point->type);
    
    // 组装数据为JSON格式
    char data_json[256];
    snprintf(data_json, sizeof(data_json),
             "{\"address\":%u,\"type\":%d,\"value\":%.2f,\"quality\":%d,\"timestamp\":%ld}",
             data_point->address,
             data_point->type,
             data_point->value.measurement,
             data_point->quality,
             data_point->timestamp);
    
    // 组装为IoT平台格式
    char* iot_data = assemble_iot_data(listener->device_name, "property", data_json, time(NULL));
    if (iot_data == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "组装IoT数据失败");
        return;
    }
    
    // 上报到IoT平台
    if (report_to_iot_platform(listener, iot_data) != 0) {
        LOG_ERROR(LOG_MODULE_NAME, "上报数据到IoT平台失败");
    }
    
    free(iot_data);
}

/**
 * @brief 监听线程函数
 */
static void* listen_thread_func(void* arg) {
    device_listener_private_t* listener = (device_listener_private_t*)arg;
    
    LOG_INFO(LOG_MODULE_NAME, "监听线程启动: 协议类型=%d", listener->protocol_type);
    
    while (listener->running) {
        switch (listener->protocol_type) {
            case 104: {
                // 104协议监听
                if (listener->protocol_104_handle != NULL) {
                    // 接收数据
                    data_point_t data_points[10];
                    int actual_count = 0;
                    
                    // TODO: 调用protocol_receive_data接收数据
                    // int result = protocol_receive_data(listener->protocol_104_handle,
                    //                                    data_points, 10, &actual_count);
                    // if (result == 0 && actual_count > 0) {
                    //     for (int i = 0; i < actual_count; i++) {
                    //         protocol_104_data_callback(&data_points[i], listener);
                    //     }
                    // }
                }
                break;
            }
            
            case 3761: {
                // 3761协议监听
                // TODO: 实现3761协议数据接收
                break;
            }
            
            case 3762: {
                // 3762协议监听
                // TODO: 实现3762协议数据接收
                break;
            }
            
            default:
                LOG_WARN(LOG_MODULE_NAME, "不支持的协议类型: %d", listener->protocol_type);
                break;
        }
        
        // 短暂休眠
        usleep(100000);  // 100ms
    }
    
    LOG_INFO(LOG_MODULE_NAME, "监听线程退出");
    return NULL;
}

/* ==================== 公开函数实现 ==================== */

device_listener_handle_t device_listener_create(int protocol_type,
                                                const char* product_key,
                                                const char* device_name,
                                                void* iot_platform_handle) {
    if (protocol_type <= 0 || product_key == NULL || device_name == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "参数无效");
        return NULL;
    }
    
    device_listener_private_t* listener = (device_listener_private_t*)calloc(1, sizeof(device_listener_private_t));
    if (listener == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "内存分配失败");
        return NULL;
    }
    
    // 初始化互斥锁
    if (pthread_mutex_init(&listener->mutex, NULL) != 0) {
        LOG_ERROR(LOG_MODULE_NAME, "互斥锁初始化失败");
        free(listener);
        return NULL;
    }
    
    listener->protocol_type = protocol_type;
    strncpy(listener->product_key, product_key, sizeof(listener->product_key) - 1);
    strncpy(listener->device_name, device_name, sizeof(listener->device_name) - 1);
    listener->iot_platform_handle = iot_platform_handle;
    listener->running = false;
    
    // 根据协议类型初始化协议句柄
    switch (protocol_type) {
        case 104: {
            // 初始化104协议
            protocol_config_t config = {0};
            // TODO: 从配置文件读取104协议参数
            // config.server_ip = "...";
            // config.server_port = 2404;
            // config.common_address = 1;
            // config.timeout_ms = 3000;
            // config.auto_reconnect = true;
            
            // listener->protocol_104_handle = protocol_create(&config);
            // if (listener->protocol_104_handle == NULL) {
            //     LOG_ERROR(LOG_MODULE_NAME, "104协议创建失败");
            //     pthread_mutex_destroy(&listener->mutex);
            //     free(listener);
            //     return NULL;
            // }
            
            // 注册数据接收回调
            // protocol_set_data_callback(listener->protocol_104_handle,
            //                           protocol_104_data_callback, listener);
            break;
        }
        
        case 3761: {
            // TODO: 初始化3761协议
            break;
        }
        
        case 3762: {
            // TODO: 初始化3762协议
            break;
        }
        
        default:
            LOG_ERROR(LOG_MODULE_NAME, "不支持的协议类型: %d", protocol_type);
            pthread_mutex_destroy(&listener->mutex);
            free(listener);
            return NULL;
    }
    
    LOG_INFO(LOG_MODULE_NAME, "设备监听器创建成功: 协议类型=%d, 设备=%s", 
             protocol_type, device_name);
    
    return (device_listener_handle_t)listener;
}

void device_listener_destroy(device_listener_handle_t handle) {
    if (handle == NULL) {
        return;
    }
    
    device_listener_private_t* listener = (device_listener_private_t*)handle;
    
    // 停止监听
    device_listener_stop(handle);
    
    pthread_mutex_lock(&listener->mutex);
    
    // 清理协议句柄
    if (listener->protocol_104_handle != NULL) {
        // protocol_disconnect(listener->protocol_104_handle);
        // protocol_destroy(listener->protocol_104_handle);
        listener->protocol_104_handle = NULL;
    }
    
    // TODO: 清理其他协议句柄
    
    pthread_mutex_unlock(&listener->mutex);
    
    pthread_mutex_destroy(&listener->mutex);
    free(listener);
    
    LOG_INFO(LOG_MODULE_NAME, "设备监听器已销毁");
}

int device_listener_start(device_listener_handle_t handle) {
    if (handle == NULL) {
        return -1;
    }
    
    device_listener_private_t* listener = (device_listener_private_t*)handle;
    
    pthread_mutex_lock(&listener->mutex);
    
    if (listener->running) {
        pthread_mutex_unlock(&listener->mutex);
        return 0;
    }
    
    listener->running = true;
    
    // 连接协议
    switch (listener->protocol_type) {
        case 104:
            if (listener->protocol_104_handle != NULL) {
                // TODO: protocol_connect(listener->protocol_104_handle);
            }
            break;
        default:
            break;
    }
    
    // 启动监听线程
    if (pthread_create(&listener->listen_thread, NULL, listen_thread_func, listener) != 0) {
        LOG_ERROR(LOG_MODULE_NAME, "创建监听线程失败");
        listener->running = false;
        pthread_mutex_unlock(&listener->mutex);
        return -1;
    }
    
    pthread_mutex_unlock(&listener->mutex);
    
    LOG_INFO(LOG_MODULE_NAME, "设备监听器已启动");
    return 0;
}

int device_listener_stop(device_listener_handle_t handle) {
    if (handle == NULL) {
        return -1;
    }
    
    device_listener_private_t* listener = (device_listener_private_t*)handle;
    
    pthread_mutex_lock(&listener->mutex);
    
    if (!listener->running) {
        pthread_mutex_unlock(&listener->mutex);
        return 0;
    }
    
    listener->running = false;
    
    pthread_mutex_unlock(&listener->mutex);
    
    // 等待线程退出
    if (pthread_join(listener->listen_thread, NULL) != 0) {
        LOG_WARN(LOG_MODULE_NAME, "等待监听线程退出失败");
    }
    
    // 断开协议连接
    switch (listener->protocol_type) {
        case 104:
            if (listener->protocol_104_handle != NULL) {
                // TODO: protocol_disconnect(listener->protocol_104_handle);
            }
            break;
        default:
            break;
    }
    
    LOG_INFO(LOG_MODULE_NAME, "设备监听器已停止");
    return 0;
}
